home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / libtiff / tif_dirwrite.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  23KB  |  828 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_dirwrite.c,v 1.28 93/06/28 16:17:38 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  *
  32.  * Directory Write Support Routines.
  33.  *
  34.  * NB: Beware of the varargs declarations for routines in
  35.  *     this file.  The names and types of variables has been
  36.  *     carefully chosen to make things work with compilers that
  37.  *     are busted in one way or another (e.g. SGI/MIPS).
  38.  */
  39. #include "tiffiop.h"
  40.  
  41. #if HAVE_IEEEFP
  42. #define    TIFFCvtNativeToIEEEFloat(tif, n, fp)
  43. #endif
  44.  
  45. #if USE_PROTOTYPES
  46. static    int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
  47. static    void TIFFSetupShortLong(TIFF *, u_short, TIFFDirEntry *, u_long);
  48. static    int TIFFSetupShortPair(TIFF *, u_short, TIFFDirEntry *);
  49. static    int TIFFWriteRational(TIFF *,
  50.         TIFFDataType, u_short, TIFFDirEntry *, float);
  51. static    int TIFFWritePerSampleShorts(TIFF *, u_short, TIFFDirEntry *);
  52. static    int TIFFWriteShortTable(TIFF *, u_short, TIFFDirEntry *, int, u_short **);
  53. static    int TIFFWriteShortArray(TIFF *,
  54.         TIFFDataType, u_short, TIFFDirEntry *, int, u_short *);
  55. static    int TIFFWriteLongArray(TIFF *,
  56.         TIFFDataType, u_short, TIFFDirEntry *, int, u_long *);
  57. static    int TIFFWriteRationalArray(TIFF *,
  58.         TIFFDataType, u_short, TIFFDirEntry *, int, float *);
  59. static    int TIFFWriteFloatArray(TIFF *,
  60.         TIFFDataType, u_short, TIFFDirEntry *, int, float *);
  61. static    int TIFFWriteString(TIFF *, u_short, TIFFDirEntry *, char *);
  62. #ifdef JPEG_SUPPORT
  63. static    int TIFFWriteJPEGQTables(TIFF *, TIFFDirEntry *);
  64. static    int TIFFWriteJPEGCTables(TIFF *, u_short, TIFFDirEntry *, u_char **);
  65. #endif
  66. #ifdef COLORIMETRY_SUPPORT
  67. static    int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
  68. #endif
  69. static    int TIFFWriteData(TIFF *, TIFFDirEntry *, char *);
  70. static    int TIFFLinkDirectory(TIFF *);
  71. #else
  72. static    int TIFFWriteNormalTag();
  73. static    void TIFFSetupShortLong();
  74. static    int TIFFSetupShortPair();
  75. static    int TIFFWriteRational();
  76. static    int TIFFWritePerSampleShorts();
  77. static    int TIFFWriteShortTable();
  78. static    int TIFFWriteShortArray();
  79. static    int TIFFWriteLongArray();
  80. static    int TIFFWriteRationalArray();
  81. static    int TIFFWriteFloatArray();
  82. static    int TIFFWriteString();
  83. #ifdef JPEG_SUPPORT
  84. static    int TIFFWriteJPEGQTables();
  85. static    int TIFFWriteJPEGCTables();
  86. #endif
  87. #ifdef COLORIMETRY_SUPPORT
  88. static    int TIFFWriteTransferFunction();
  89. #endif
  90. static    int TIFFWriteData();
  91. static    int TIFFLinkDirectory();
  92. #endif
  93.  
  94. #define    WriteRationalPair(type, tag1, v1, tag2, v2) {        \
  95.     if (!TIFFWriteRational(tif, type, tag1, dir, v1))    \
  96.         goto bad;                    \
  97.     if (!TIFFWriteRational(tif, type, tag2, dir+1, v2))    \
  98.         goto bad;                    \
  99.     dir++;                            \
  100. }
  101.  
  102. /*
  103.  * Write the contents of the current directory
  104.  * to the specified file.  This routine doesn't
  105.  * handle overwriting a directory with auxiliary
  106.  * storage that's been changed.
  107.  */
  108. int
  109. DECLARE1(TIFFWriteDirectory, TIFF*, tif)
  110. {
  111.     short dircount, tag;
  112.     int nfields, dirsize;
  113.     char *data;
  114.     const TIFFFieldInfo *fip;
  115.     TIFFDirEntry *dir;
  116.     TIFFDirectory *td;
  117.     u_long b, fields[FIELD_SETLONGS];
  118.  
  119.     if (tif->tif_mode == O_RDONLY)
  120.         return (1);
  121.     /*
  122.      * Clear write state so that subsequent images with
  123.      * different characteristics get the right buffers
  124.      * setup for them.
  125.      */
  126.     if (tif->tif_flags & TIFF_POSTENCODE) {
  127.         tif->tif_flags &= ~TIFF_POSTENCODE;
  128.         if (tif->tif_postencode && !(*tif->tif_postencode)(tif)) {
  129.             TIFFError(tif->tif_name,
  130.                 "Error post-encoding before directory write");
  131.             return (0);
  132.         }
  133.     }
  134.     if (tif->tif_close)
  135.         (*tif->tif_close)(tif);
  136.     if (tif->tif_cleanup)
  137.         (*tif->tif_cleanup)(tif);
  138.     /*
  139.      * Flush any data that might have been written
  140.      * by the compression close+cleanup routines.
  141.      */
  142.     if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
  143.         TIFFError(tif->tif_name,
  144.             "Error flushing data before directory write");
  145.         return (0);
  146.     }
  147.     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
  148.         _TIFFfree(tif->tif_rawdata);
  149.         tif->tif_rawdata = NULL;
  150.         tif->tif_rawcc = 0;
  151.     }
  152.     tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
  153.  
  154.     td = &tif->tif_dir;
  155.     /*
  156.      * Size the directory so that we can calculate
  157.      * offsets for the data items that aren't kept
  158.      * in-place in each field.
  159.      */
  160.     nfields = 0;
  161.     for (b = 0; b <= FIELD_LAST; b++)
  162.         if (TIFFFieldSet(tif, b))
  163.             nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
  164.     dirsize = nfields * sizeof (TIFFDirEntry);
  165.     data = _TIFFmalloc(dirsize);
  166.     if (data == NULL) {
  167.         TIFFError(tif->tif_name,
  168.             "Cannot write directory, out of space");
  169.         return (0);
  170.     }
  171.     /*
  172.      * Directory hasn't been placed yet, put
  173.      * it at the end of the file and link it
  174.      * into the existing directory structure.
  175.      */
  176.     if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
  177.         goto bad;
  178.     tif->tif_dataoff =
  179.         tif->tif_diroff + sizeof (short) + dirsize + sizeof (long);
  180.     if (tif->tif_dataoff & 1)
  181.         tif->tif_dataoff++;
  182.     (void) TIFFSeekFile(tif, tif->tif_dataoff, L_SET);
  183.     tif->tif_curdir++;
  184.     dir = (TIFFDirEntry *)data;
  185.     /*
  186.      * Setup external form of directory
  187.      * entries and write data items.
  188.      */
  189.     memcpy(fields, td->td_fieldsset, sizeof (fields));
  190. /*BEGIN XXX*/
  191.     /*
  192.      * Write out ExtraSamples tag only if Matteing would
  193.      * be set to 1 (i.e. Associated Alpha data is present).
  194.      */
  195.     if (FieldSet(fields, FIELD_MATTEING) && !td->td_matteing) {    /*XXX*/
  196.         ResetFieldBit(fields, FIELD_MATTEING);            /*XXX*/
  197.         nfields--;                        /*XXX*/
  198.         dirsize -= sizeof (TIFFDirEntry);            /*XXX*/
  199.     }                                /*XXX*/
  200. /*END XXX*/
  201.     for (fip = tiffFieldInfo; fip->field_tag; fip++) {
  202.         if (fip->field_bit == FIELD_IGNORE ||
  203.             !FieldSet(fields, fip->field_bit))
  204.             continue;
  205.         switch (fip->field_bit) {
  206.         case FIELD_STRIPOFFSETS:
  207.             /*
  208.              * We use one field bit for both strip and tile
  209.              * offsets, and so must be careful in selecting
  210.              * the appropriate field descriptor (so that tags
  211.              * are written in sorted order).
  212.              */
  213.             tag = isTiled(tif) ?
  214.                 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
  215.             if (tag != fip->field_tag)
  216.                 continue;
  217.             if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
  218.                 (int) td->td_nstrips, td->td_stripoffset))
  219.                 goto bad;
  220.             break;
  221.         case FIELD_STRIPBYTECOUNTS:
  222.             /*
  223.              * We use one field bit for both strip and tile
  224.              * byte counts, and so must be careful in selecting
  225.              * the appropriate field descriptor (so that tags
  226.              * are written in sorted order).
  227.              */
  228.             tag = isTiled(tif) ?
  229.                 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
  230.             if (tag != fip->field_tag)
  231.                 continue;
  232.             if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
  233.                 (int) td->td_nstrips, td->td_stripbytecount))
  234.                 goto bad;
  235.             break;
  236.         case FIELD_ROWSPERSTRIP:
  237.             TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
  238.                 dir, td->td_rowsperstrip);
  239.             break;
  240.         case FIELD_COLORMAP:
  241.             if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
  242.                 3, td->td_colormap))
  243.                 goto bad;
  244.             break;
  245.         case FIELD_IMAGEDIMENSIONS:
  246.             TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
  247.                 dir++, td->td_imagewidth);
  248.             TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
  249.                 dir, td->td_imagelength);
  250.             break;
  251.         case FIELD_TILEDIMENSIONS:
  252.             TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
  253.                 dir++, td->td_tilewidth);
  254.             TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
  255.                 dir, td->td_tilelength);
  256.             break;
  257.         case FIELD_POSITION:
  258.             WriteRationalPair(TIFF_RATIONAL,
  259.                 TIFFTAG_XPOSITION, td->td_xposition,
  260.                 TIFFTAG_YPOSITION, td->td_yposition);
  261.             break;
  262.         case FIELD_RESOLUTION:
  263.             WriteRationalPair(TIFF_RATIONAL,
  264.                 TIFFTAG_XRESOLUTION, td->td_xresolution,
  265.                 TIFFTAG_YRESOLUTION, td->td_yresolution);
  266.             break;
  267.         case FIELD_BITSPERSAMPLE:
  268.         case FIELD_MINSAMPLEVALUE:
  269.         case FIELD_MAXSAMPLEVALUE:
  270.         case FIELD_SAMPLEFORMAT:
  271.             if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
  272.                 goto bad;
  273.             break;
  274.         case FIELD_PAGENUMBER:
  275.         case FIELD_HALFTONEHINTS:
  276. #ifdef YCBCR_SUPPORT
  277.         case FIELD_YCBCRSUBSAMPLING:
  278. #endif
  279. #ifdef CMYK_SUPPORT
  280.         case FIELD_DOTRANGE:
  281. #endif
  282.             if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
  283.                 goto bad;
  284.             break;
  285. #ifdef JPEG_SUPPORT
  286.         case FIELD_JPEGQTABLES:
  287.             if (!TIFFWriteJPEGQTables(tif, dir))
  288.                 goto bad;
  289.             break;
  290.         case FIELD_JPEGDCTABLES:
  291.             if (!TIFFWriteJPEGCTables(tif,
  292.                 TIFFTAG_JPEGDCTABLES, dir, td->td_dctab))
  293.                 goto bad;
  294.             break;
  295.         case FIELD_JPEGACTABLES:
  296.             if (!TIFFWriteJPEGCTables(tif,
  297.                 TIFFTAG_JPEGACTABLES, dir, td->td_actab))
  298.                 goto bad;
  299.             break;
  300. #endif
  301. #ifdef COLORIMETRY_SUPPORT
  302.         case FIELD_TRANSFERFUNCTION:
  303.             if (!TIFFWriteTransferFunction(tif, dir))
  304.                 goto bad;
  305.             break;
  306. #endif
  307.         default:
  308.             if (!TIFFWriteNormalTag(tif, dir, fip))
  309.                 goto bad;
  310.             break;
  311.         }
  312.         dir++;
  313.         ResetFieldBit(fields, fip->field_bit);
  314.     }
  315.     /*
  316.      * Write directory.
  317.      */
  318.     (void) TIFFSeekFile(tif, tif->tif_diroff, L_SET);
  319.     dircount = nfields;
  320.     if (!WriteOK(tif, &dircount, sizeof (short))) {
  321.         TIFFError(tif->tif_name, "Error writing directory count");
  322.         goto bad;
  323.     }
  324.     if (!WriteOK(tif, data, dirsize)) {
  325.         TIFFError(tif->tif_name, "Error writing directory contents");
  326.         goto bad;
  327.     }
  328.     if (!WriteOK(tif, &tif->tif_nextdiroff, sizeof (long))) {
  329.         TIFFError(tif->tif_name, "Error writing directory link");
  330.         goto bad;
  331.     }
  332.     TIFFFreeDirectory(tif);
  333.     _TIFFfree(data);
  334.     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
  335.  
  336.     /*
  337.      * Reset directory-related state for subsequent
  338.      * directories.
  339.      */
  340.     TIFFDefaultDirectory(tif);
  341.     tif->tif_diroff = 0;
  342.     tif->tif_curoff = 0;
  343.     tif->tif_row = -1;
  344.     tif->tif_curstrip = -1;
  345.     return (1);
  346. bad:
  347.     _TIFFfree(data);
  348.     return (0);
  349. }
  350. #undef WriteRationalPair
  351.  
  352. /*
  353.  * Process tags that are not special cased.
  354.  */
  355. static int
  356. DECLARE3(TIFFWriteNormalTag,
  357.     TIFF*, tif, TIFFDirEntry*, dir, const TIFFFieldInfo*, fip)
  358. {
  359.     TIFFDirectory* td = &tif->tif_dir;
  360.     u_short wc = (u_short) fip->field_writecount;
  361.  
  362.     dir->tdir_tag = fip->field_tag;
  363.     dir->tdir_type = (u_short)fip->field_type;
  364.     dir->tdir_count = wc;
  365. #define    WRITE(x,y)    x(tif, fip->field_type, fip->field_tag, dir, wc, y)
  366.     switch (fip->field_type) {
  367.     case TIFF_SHORT:
  368.     case TIFF_SSHORT:
  369.         if (wc > 1) {
  370.             u_short *wp;
  371.             if (wc == (u_short) TIFF_VARIABLE) {
  372.                 _TIFFgetfield(td, fip->field_tag, &wc, &wp);
  373.                 dir->tdir_count = wc;
  374.             } else
  375.                 _TIFFgetfield(td, fip->field_tag, &wp);
  376.             if (!WRITE(TIFFWriteShortArray, wp))
  377.                 return (0);
  378.         } else {
  379.             u_short sv;
  380.             _TIFFgetfield(td, fip->field_tag, &sv);
  381.             dir->tdir_offset =
  382.                 TIFFInsertData(tif, dir->tdir_type, sv);
  383.         }
  384.         break;
  385.     case TIFF_LONG:
  386.     case TIFF_SLONG:
  387.         if (wc > 1) {
  388.             u_long *lp;
  389.             if (wc == (u_short) TIFF_VARIABLE) {
  390.                 _TIFFgetfield(td, fip->field_tag, &wc, &lp);
  391.                 dir->tdir_count = wc;
  392.             } else
  393.                 _TIFFgetfield(td, fip->field_tag, &lp);
  394.             if (!WRITE(TIFFWriteLongArray, lp))
  395.                 return (0);
  396.         } else {
  397.             /* XXX handle LONG->SHORT conversion */
  398.             _TIFFgetfield(td, fip->field_tag, &dir->tdir_offset);
  399.         }
  400.         break;
  401.     case TIFF_RATIONAL:
  402.     case TIFF_SRATIONAL:
  403.         if (wc > 1) {
  404.             float *fp;
  405.             if (wc == (u_short) TIFF_VARIABLE) {
  406.                 _TIFFgetfield(td, fip->field_tag, &wc, &fp);
  407.                 dir->tdir_count = wc;
  408.             } else
  409.                 _TIFFgetfield(td, fip->field_tag, &fp);
  410.             if (!WRITE(TIFFWriteRationalArray, fp))
  411.                 return (0);
  412.         } else {
  413.             float fv;
  414.             _TIFFgetfield(td, fip->field_tag, &fv);
  415.             if (!TIFFWriteRational(tif, fip->field_type, fip->field_tag, dir, fv))
  416.                 return (0);
  417.         }
  418.         break;
  419.     case TIFF_FLOAT:
  420.         if (wc > 1) {
  421.             float *fp;
  422.             if (wc == (u_short) TIFF_VARIABLE) {
  423.                 _TIFFgetfield(td, fip->field_tag, &wc, &fp);
  424.                 dir->tdir_count = wc;
  425.             } else
  426.                 _TIFFgetfield(td, fip->field_tag, &fp);
  427.             if (!WRITE(TIFFWriteFloatArray, fp))
  428.                 return (0);
  429.         } else {
  430.             float fv;
  431.             _TIFFgetfield(td, fip->field_tag, &fv);
  432.             TIFFCvtNativeToIEEEFloat(tif, 1, &fv);
  433.             /* XXX assumes sizeof (long) == sizeof (float) */
  434.             dir->tdir_offset = *(u_long *)&fv;    /* XXX */
  435.         }
  436.         break;
  437.     case TIFF_ASCII: {
  438.         char *cp;
  439.         _TIFFgetfield(td, fip->field_tag, &cp);
  440.         if (!TIFFWriteString(tif, fip->field_tag, dir, cp))
  441.             return (0);
  442.         break;
  443.     }
  444.     }
  445.     return (1);
  446. }
  447. #undef WRITE
  448.  
  449. /*
  450.  * Setup a directory entry with either a SHORT
  451.  * or LONG type according to the value.
  452.  */
  453. static void
  454. DECLARE4(TIFFSetupShortLong,
  455.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, u_long, v)
  456. {
  457.     dir->tdir_tag = tag;
  458.     dir->tdir_count = 1;
  459.     if (v > 0xffffL) {
  460.         dir->tdir_type = (short)TIFF_LONG;
  461.         dir->tdir_offset = v;
  462.     } else {
  463.         dir->tdir_type = (short)TIFF_SHORT;
  464.         dir->tdir_offset = TIFFInsertData(tif, (int)TIFF_SHORT, v);
  465.     }
  466. }
  467. #undef MakeShortDirent
  468.  
  469. /*
  470.  * Setup a RATIONAL directory entry and
  471.  * write the associated indirect value.
  472.  */
  473. static int
  474. DECLARE5(TIFFWriteRational,
  475.     TIFF*, tif, TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, float, v)
  476. {
  477.     return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v));
  478. }
  479.  
  480. #define    NITEMS(x)    (sizeof (x) / sizeof (x[0]))
  481. /*
  482.  * Setup a directory entry that references a
  483.  * samples/pixel array of SHORT values and
  484.  * (potentially) write the associated indirect
  485.  * values.
  486.  */
  487. static int
  488. DECLARE3(TIFFWritePerSampleShorts,
  489.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir)
  490. {
  491.     u_short buf[10], v;
  492.     u_short* w = buf;
  493.     int i, status, samples = tif->tif_dir.td_samplesperpixel;
  494.  
  495.     if (samples > NITEMS(buf))
  496.         w = (u_short *)_TIFFmalloc(samples * sizeof (u_short));
  497.     _TIFFgetfield(&tif->tif_dir, tag, &v);
  498.     for (i = 0; i < samples; i++)
  499.         w[i] = v;
  500.     status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w);
  501.     if (w != buf)
  502.         _TIFFfree((char*)w);
  503.     return (status);
  504. }
  505. #undef NITEMS
  506.  
  507. /*
  508.  * Setup a pair of shorts that are returned by
  509.  * value, rather than as a reference to an array.
  510.  */
  511. static int
  512. DECLARE3(TIFFSetupShortPair,
  513.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir)
  514. {
  515.     u_short v[2];
  516.  
  517.     _TIFFgetfield(&tif->tif_dir, tag, &v[0], &v[1]);
  518.     return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
  519. }
  520.  
  521. /*
  522.  * Setup a directory entry for an NxM table of shorts,
  523.  * where M is known to be 2**bitspersample, and write
  524.  * the associated indirect data.
  525.  */
  526. static int
  527. DECLARE5(TIFFWriteShortTable,
  528.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, int, n, u_short**, table)
  529. {
  530.     u_long off;
  531.     int i;
  532.  
  533.     dir->tdir_tag = tag;
  534.     dir->tdir_type = (short)TIFF_SHORT;
  535.     /* XXX -- yech, fool TIFFWriteData */
  536.     dir->tdir_count = 1L<<tif->tif_dir.td_bitspersample;
  537.     off = tif->tif_dataoff;
  538.     for (i = 0; i < n; i++)
  539.         if (!TIFFWriteData(tif, dir, (char *)table[i]))
  540.             return (0);
  541.     dir->tdir_count *= n;
  542.     dir->tdir_offset = off;
  543.     return (1);
  544. }
  545.  
  546. /*
  547.  * Setup a directory entry of an ASCII string
  548.  * and write any associated indirect value.
  549.  */
  550. static int
  551. DECLARE4(TIFFWriteString,
  552.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, char*, cp)
  553. {
  554.     dir->tdir_tag = tag;
  555.     dir->tdir_type = (short)TIFF_ASCII;
  556.     dir->tdir_count = strlen(cp) + 1;    /* includes \0 byte */
  557.     if (dir->tdir_count > 4) {
  558.         if (!TIFFWriteData(tif, dir, cp))
  559.             return (0);
  560.     } else
  561.         memcpy(&dir->tdir_offset, cp, dir->tdir_count);
  562.     return (1);
  563. }
  564.  
  565. /*
  566.  * Setup a directory entry of an array of SHORT
  567.  * or SSHORT and write the associated indirect values.
  568.  */
  569. static int
  570. DECLARE6(TIFFWriteShortArray, TIFF*, tif,
  571.     TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, int, n, u_short*, v)
  572. {
  573.     dir->tdir_tag = tag;
  574.     dir->tdir_type = (short)type;
  575.     dir->tdir_count = n;
  576.     if (n <= 2) {
  577.         if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
  578.             dir->tdir_offset = (long)v[0] << 16;
  579.             if (n == 2)
  580.                 dir->tdir_offset |= v[1] & 0xffff;
  581.         } else {
  582.             dir->tdir_offset = v[0] & 0xffff;
  583.             if (n == 2)
  584.                 dir->tdir_offset |= (long)v[1] << 16;
  585.         }
  586.         return (1);
  587.     } else
  588.         return (TIFFWriteData(tif, dir, (char *)v));
  589. }
  590.  
  591. /*
  592.  * Setup a directory entry of an array of LONG
  593.  * or SLONG and write the associated indirect values.
  594.  */
  595. static int
  596. DECLARE6(TIFFWriteLongArray, TIFF*, tif,
  597.     TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, int, n, u_long*, v)
  598. {
  599.     dir->tdir_tag = tag;
  600.     dir->tdir_type = (short)type;
  601.     dir->tdir_count = n;
  602.     if (n == 1) {
  603.         dir->tdir_offset = v[0];
  604.         return (1);
  605.     } else
  606.         return (TIFFWriteData(tif, dir, (char *)v));
  607. }
  608.  
  609. /*
  610.  * Setup a directory entry of an array of RATIONAL
  611.  * or SRATIONAL and write the associated indirect values.
  612.  */
  613. static int
  614. DECLARE6(TIFFWriteRationalArray, TIFF*, tif,
  615.     TIFFDataType, type, u_short, tag, TIFFDirEntry*, dir, int, n, float*, v)
  616. {
  617.     int i, status;
  618.     u_long *t;
  619.  
  620.     dir->tdir_tag = tag;
  621.     dir->tdir_type = (short)type;
  622.     dir->tdir_count = n;
  623.     t = (u_long *)_TIFFmalloc(2*n * sizeof (long));
  624.     for (i = 0; i < n; i++) {
  625.         float fv = v[i];
  626.         int sign = 1;
  627.         u_long den;
  628.  
  629.         if (fv < 0) {
  630.             if (type == TIFF_RATIONAL) {
  631.                 TIFFWarning(tif->tif_name,
  632.     "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
  633.                     TIFFFieldWithTag(tag)->field_name, v);
  634.                 fv = 0;
  635.             } else
  636.                 fv = -fv, sign = -1;
  637.         }
  638.         den = 1L;
  639.         if (fv > 0) {
  640.             while (fv < 1L<<(31-3) && den < 1L<<(31-3))
  641.                 fv *= 1<<3, den *= 1L<<3;
  642.         }
  643.         t[2*i+0] = sign * (fv + 0.5);
  644.         t[2*i+1] = den;
  645.     }
  646.     status = TIFFWriteData(tif, dir, (char *)t);
  647.     _TIFFfree((char *)t);
  648.     return (status);
  649. }
  650.  
  651. static int
  652. DECLARE6(TIFFWriteFloatArray, TIFF *, tif,
  653.     TIFFDataType, type, u_short, tag, TIFFDirEntry *, dir, int, n, float *, v)
  654. {
  655.     dir->tdir_tag = tag;
  656.     dir->tdir_type = (short)type;
  657.     dir->tdir_count = n;
  658.     TIFFCvtNativeToIEEEFloat(tif, n, v);
  659.     if (n == 1) {
  660.         dir->tdir_offset = *(u_long *)&v[0];
  661.         return (1);
  662.     } else
  663.         return (TIFFWriteData(tif, dir, (char *)v));
  664. }
  665.  
  666. #ifdef JPEG_SUPPORT
  667. #define    NITEMS(x)    (sizeof (x) / sizeof (x[0]))
  668. /*
  669.  * Setup a directory entry for JPEG Quantization
  670.  * tables and write the associated indirect values.
  671.  */
  672. static int
  673. DECLARE2(TIFFWriteJPEGQTables, TIFF*, tif, TIFFDirEntry*, dir)
  674. {
  675.     int i, status = 0, samples = tif->tif_dir.td_samplesperpixel;
  676.     u_long buf[10], *off = buf;
  677.     TIFFDirEntry tdir;
  678.  
  679.     tdir.tdir_tag = TIFFTAG_JPEGQTABLES;    /* for diagnostics */
  680.     tdir.tdir_type = (short)TIFF_BYTE;
  681.     tdir.tdir_count = 64;
  682.     if (samples > NITEMS(buf))
  683.         off = (u_long*)_TIFFmalloc(samples * sizeof (u_long));
  684.     for (i = 0; i < samples; i++) {
  685.         if (!TIFFWriteData(tif, &tdir, (char *)tif->tif_dir.td_qtab[i]))
  686.             goto bad;
  687.         off[i] = tdir.tdir_offset;
  688.     }
  689.     status = TIFFWriteLongArray(tif, TIFF_LONG,
  690.         TIFFTAG_JPEGQTABLES, dir, samples, off);
  691. bad:
  692.     if (off != buf)
  693.         _TIFFfree((char*)off);
  694.     return (status);
  695. }
  696.  
  697. /*
  698.  * Setup a directory entry for JPEG Coefficient
  699.  * tables and write the associated indirect values.
  700.  */
  701. static int
  702. DECLARE4(TIFFWriteJPEGCTables,
  703.     TIFF*, tif, u_short, tag, TIFFDirEntry*, dir, u_char **, tab)
  704. {
  705.     int status = 0, samples = tif->tif_dir.td_samplesperpixel;
  706.     u_long buf[10], *off = buf;
  707.     TIFFDirEntry tdir;
  708.     int i, j, ncodes;
  709.  
  710.     tdir.tdir_tag = tag;        /* for diagnostics */
  711.     tdir.tdir_type = (short)TIFF_BYTE;
  712.     if (samples > NITEMS(buf))
  713.         off = (u_long*)_TIFFmalloc(samples * sizeof (u_long));
  714.     for (i = 0; i < samples; i++) {
  715.         for (ncodes = 0, j = 0; j < 16; j++)
  716.             ncodes += tab[i][j];
  717.         tdir.tdir_count = 16+ncodes;
  718.         if (!TIFFWriteData(tif, &tdir, (char *)tab[i]))
  719.             goto bad;
  720.         off[i] = tdir.tdir_offset;
  721.     }
  722.     status = TIFFWriteLongArray(tif, TIFF_LONG, tag, dir, samples, off);
  723. bad:
  724.     if (off != buf)
  725.         _TIFFfree((char*)off);
  726.     return (status);
  727. }
  728. #undef NITEMS
  729. #endif
  730.  
  731. #ifdef COLORIMETRY_SUPPORT
  732. static int
  733. DECLARE2(TIFFWriteTransferFunction, TIFF*, tif, TIFFDirEntry*, dir)
  734. {
  735.     TIFFDirectory *td = &tif->tif_dir;
  736.     u_long n = (1L<<td->td_bitspersample) * sizeof (u_short);
  737.     u_short **tf = td->td_transferfunction;
  738.     int ncols;
  739.  
  740.     /*
  741.      * Check if the table can be written as a single column,
  742.      * or if it must be written as 3 columns.  Note that we
  743.      * write a 3-column tag if there are 2 samples/pixel and
  744.      * a single column of data won't suffice--hmm.
  745.      */
  746.     switch (td->td_samplesperpixel - td->td_matteing) {
  747.     default:    if (memcmp(tf[0], tf[2], n)) { ncols = 3; break; }
  748.     case 2:        if (memcmp(tf[0], tf[1], n)) { ncols = 3; break; }
  749.     case 1: case 0:    ncols = 1;
  750.     }
  751.     return (TIFFWriteShortTable(tif,
  752.         TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
  753. }
  754. #endif
  755.  
  756. /*
  757.  * Write a contiguous directory item.
  758.  */
  759. static int
  760. DECLARE3(TIFFWriteData, TIFF*, tif, TIFFDirEntry*, dir, char*, cp)
  761. {
  762.     int cc;
  763.  
  764.     dir->tdir_offset = tif->tif_dataoff;
  765.     cc = dir->tdir_count * tiffDataWidth[dir->tdir_type];
  766.     if (SeekOK(tif, dir->tdir_offset) &&
  767.         WriteOK(tif, cp, cc)) {
  768.         tif->tif_dataoff += (cc + 1) & ~1;
  769.         return (1);
  770.     }
  771.     TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
  772.         TIFFFieldWithTag(dir->tdir_tag)->field_name);
  773.     return (0);
  774. }
  775.  
  776. /*
  777.  * Link the current directory into the
  778.  * directory chain for the file.
  779.  */
  780. static int
  781. DECLARE1(TIFFLinkDirectory, TIFF*, tif)
  782. {
  783.     static const char module[] = "TIFFLinkDirectory";
  784.     u_short dircount;
  785.     long nextdir;
  786.  
  787.     tif->tif_diroff = (TIFFSeekFile(tif, 0L, L_XTND)+1) &~ 1L;
  788.     if (tif->tif_header.tiff_diroff == 0) {
  789.         /*
  790.          * First directory, overwrite header.
  791.          */
  792.         tif->tif_header.tiff_diroff = tif->tif_diroff;
  793.         (void) TIFFSeekFile(tif, 0L, L_SET);
  794.         if (!WriteOK(tif, &tif->tif_header,
  795.             sizeof (tif->tif_header))) {
  796.             TIFFError(tif->tif_name, "Error writing TIFF header");
  797.             return (0);
  798.         }
  799.         return (1);
  800.     }
  801.     /*
  802.      * Not the first directory, search to the last and append.
  803.      */
  804.     nextdir = tif->tif_header.tiff_diroff;
  805.     do {
  806.         if (!SeekOK(tif, nextdir) ||
  807.             !ReadOK(tif, &dircount, sizeof (dircount))) {
  808.             TIFFError(module, "Error fetching directory count");
  809.             return (0);
  810.         }
  811.         if (tif->tif_flags & TIFF_SWAB)
  812.             TIFFSwabShort(&dircount);
  813.         TIFFSeekFile(tif, dircount * sizeof (TIFFDirEntry), L_INCR);
  814.         if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
  815.             TIFFError(module, "Error fetching directory link");
  816.             return (0);
  817.         }
  818.         if (tif->tif_flags & TIFF_SWAB)
  819.             TIFFSwabLong((u_long *)&nextdir);
  820.     } while (nextdir != 0);
  821.     (void) TIFFSeekFile(tif, -sizeof (nextdir), L_INCR);
  822.     if (!WriteOK(tif, &tif->tif_diroff, sizeof (tif->tif_diroff))) {
  823.         TIFFError(module, "Error writing directory link");
  824.         return (0);
  825.     }
  826.     return (1);
  827. }
  828.